#include <cppunit/config/SourcePrefix.h>
#include "ParserTest.h"
#include <iostream>
#include <string>
#include <fstream>
#include <stdio.h>
#include "Parser.h"

using namespace std;

void
ParserTest::setUp()
{}
void
ParserTest::tearDown()
{}

CPPUNIT_TEST_SUITE_REGISTRATION( ParserTest );

void ParserTest::testStartParsing(){
	//parse the SIMPLE source code into the parser
	cout << "Testing : bool Parser::startParsing(string)" << endl;
	PKB* pkb = new PKB();
	Parser* p = new Parser(pkb);
	string filename = "../Release/alfathiOneTidy.txt";
	p->startParsing(filename);

	cout << "- modifiesTableStmt" << endl;
	CPPUNIT_ASSERT(p->myPKB->modifies->modifiesTableStmt.size() == 25);
	
	cout << "- followsTableStmt" << endl;
	CPPUNIT_ASSERT(p->myPKB->follows->followsTableStmt.size() == 25);
	
	cout << "- callsTableStmt" << endl;
	CPPUNIT_ASSERT(p->myPKB->calls->callsTableStmt.empty());
	
	cout << "- constTableStmt" << endl;
	CPPUNIT_ASSERT(p->myPKB->ast->constTable.size() == 6);
	
	cout << "- parentTableStmt" << endl;
	CPPUNIT_ASSERT(p->myPKB->parent->parentTableStmt.size() == 34);
	
	cout << "- procTable" << endl;
	CPPUNIT_ASSERT(p->myPKB->procTable->procTable.size() == 1);

	cout << "- stmtTable" << endl;
	CPPUNIT_ASSERT(p->myPKB->stmtTable->stmtTable.size() == 37);
	
	cout << "Test OK : bool Parser::startParsing(string)" << endl;
}

void ParserTest::testValidateName(){
	cout << "Testing : void Parser::validateNAME(string str)" << endl;
	Parser* parser;
	string str1, str2, str3, str4;
	str1 = "One";
	str2 = "1";
	str3 = "!";
	str4 = "One !";
	PKB* pkb = new PKB();
	parser = new Parser(pkb);

	//no exception is thrown
	CPPUNIT_ASSERT_NO_THROW(parser->validateNAME(str1));
	
	//exception is thrown
	try{
		parser->validateNAME(str2);
	}
	catch(exception& e){
		CPPUNIT_ASSERT(e.what() == "Invalid NAME in SIMPLE source code");
	}
	
	try{
		parser->validateNAME(str3);
	}
	catch(exception& e){
		CPPUNIT_ASSERT(e.what() == "Invalid NAME in SIMPLE source code");
	}

	try{
		parser->validateNAME(str4);
	}
	catch(exception& e){
		CPPUNIT_ASSERT(e.what() == "Invalid NAME in SIMPLE source code");
	}
	cout << "Test OK  : void Parser::validateNAME(string str)" << endl;
}

void ParserTest::testCheckName(){
	cout << "Testing : bool Parser::checkNAME(string str)" << endl;
	Parser* parser;
	PKB* pkb = new PKB();
	parser = new Parser(pkb);
	string str1, str2, str3, str4, str5;
	str1 = "hellothere123";
	str2 = "2meowwoofmooo";
	str3 = "meow2moo*%#@!";
	str4 = "hello e@#$";
	str5 = "e@##$ hello";
	CPPUNIT_ASSERT_EQUAL(true, parser->checkNAME(str1));
	CPPUNIT_ASSERT_EQUAL(false, parser->checkNAME(str2));
	CPPUNIT_ASSERT_EQUAL(false, parser->checkNAME(str3));
	CPPUNIT_ASSERT_EQUAL(false, parser->checkNAME(str4));
	CPPUNIT_ASSERT_EQUAL(false, parser->checkNAME(str5));
	cout << "Test OK  : bool Parser::checkNAME(string str)" << endl;
}